iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
Mobile Development

30 天輕鬆學會 Flutter 測試系列 第 25

Day 25 我該測試什麼?

  • 分享至 

  • xImage
  •  

當我們知道怎麼寫單元測試,怎麼寫 Widget Test 之後,很快就會碰到一個問題,那就是我該測試什麼?我們都知道,測試應該是要驗證需求,驗證功能是不是正確的,這個定義似乎很清楚,但是實際開始寫的時候,有時候就會遇到一些問題,今天就來談談。

要不要測試日誌記錄?

讓我們看一段程式碼,在這個方法中,除了主要處理建立訂單的商業邏輯之外,方法裡還多 log 了起迄時間,以便未來查找問題。

void store(Product product) {
	log("store ${product.id} start at ${DateTime.now()}");
	
	if (product.price > wallet.money) {
		throw MoneyNotEnoughException();
	}
	_orderRepository.create(product);
	
	log("store ${product.id} end at ${DateTime.now()}");
}

在先前的練習中,我們會測試商品購買成功與購買失敗的行為,那我們要測試 log 嗎?再讓我們看個例子。

PS. 請注意,上面 log 用法只是舉例,實務上會有更好的方式。

要不要測試顏色是否正確?

在先前的例子中,我們顯示剩餘數量的畫面中,當數量小於 10 時,會特別把文字標成紅色,讓強化使用者的感受。

1.png

Text(
  quantity.toString(),
  style: TextStyle(color: quantity < 10 ? Colors.red : Colors.black),
),

在這個例子中,我們要不要測試文字顏色呢?甚至是長寬高的顏色,或者按鈕的顏色,是不是都需要測試呢?

回到一開始的目的,我們要測試的程式功能有沒有正常,是不是跟需求一致。

什麼是需求?

開發人員在開工前可能參加 Planning,討論這個 Sprint 要做什麼,針對不同的任務討論這邊的功能是如何如何,那邊的功能是如何如何,可能也會收到一份設計稿,上面標示了按鈕要多大,對話框要放在什麼位置,背景要什麼顏色,字體要用多大。我們從設計師手中拿到設計稿。接著回到團隊,又會從系統角度開始討論任務要如何完成,架構應該怎麼調整,出錯時怎麼送出通知 …等。最後每個任務都包含了很多各種需求,其中有商業需求,有工程需求,有增加使用者體驗的需求。

把時間花在刀口上

如果我們擁有無限的時間,那我們當然可以把商業需求與增加使用者體驗的需求都加上測試,既確保了功能正常,也確保了使用者可以有最好的體驗。但現實總是殘酷的,只要產品還在發展,我們就會有無止盡的工作,必須評估每個任務的價值。如果我們發現花時間寫的東西的效益不高,那我們可以與團隊討論,決定是否轉頭去做更有價值的事情。

顏色就不重要嗎?

那是不是顏色或字體大小就不重要了呢?非也,想像一下,假設我們今天是在開發一個小畫家的功能,那我們需不需要測試使用者用紅色畫筆在畫布上畫出紅色線條呢?或者是我們的程式可以讓使用者調整字體大小,在這種情況下,我們是不是該測試使用者調整過後,字體有沒有如預期的變大變小呢?

其實我們無法一概而論的說什麼東西一定不用測試,什麼東西一定要測試,更多時候是依據價值來決定,什麼東西重要,什麼東西不重要,都是根據需求的不同,而會有不同的情況。

不要測試套件

同樣的,在測試的時候,我們大多情況下會隔離框架或第三方套件,我們只測試我們必須要維護的程式碼,大多時候我們會傾向於相信第三方的程式碼正常運作,甚至是有測試過的,畢竟如果我們不相信它的話?那我們為什麼還使用它呢?。這邊需要注意的是,我們不測試的是第三方套件 API 的行為,但是我們還是有可能會需要測試我們是否正確地使用了第三方套件。

不測試 Private 方法

一個類別會包含各種 scope 的方法:public、private、protect 方法 …等。那我們是否該測試類別中的所有方法呢?答案是不需要,以單元測試來說,我們想測試的是類別行為。只要程式中不存在冗余的程式碼,類別中的除了 public 之外的所有方法,最終應該都被某個 public 方法使用到,透過測試這個 public 方法,private 方法的行為自然也能被測試到。

如果我們硬是要測試某個 private 反倒是破壞了類別的封裝,讓測試對類別的認識過於細節,也將容易導致測試脆弱的問題。

或許有些時候,開發人員會發現從 public 方法開始測試的話,會需要準備很多資料,讓測試變得難寫,所以乾脆就直接測試 private 方法或者索性把 private 方法改成 public 方法。但其實都是不好的,就前面文章一再提到的,不好測試的時候,我們應該回頭檢視設計,而非妥協不好的設計。

小結

確保我們在寫有用的測試,也是身為專業開發人員的職責,畢竟我們得把時間花在有價值的地方。就像 Kent Beck 說「I get paid for code that works, not for tests」,我們寫測試的最終目的還是為了可用的程式,追求每一個角落都要被測試,可能反而本末倒置。


上一篇
Day 24 為什麼要寫測試?
下一篇
Day 26 我該怎麼測試?
系列文
30 天輕鬆學會 Flutter 測試30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言